#ifndef ANIMATIONSTRATEGY_H
#define ANIMATIONSTRATEGY_H

#pragma once

#include "../../ToolkitLayer.h"
#include <LDF/VisComponentStrategy.h>
#include <LDF/VisComponent.h>
#include <LDF/LargeDisplayManager.h>

/**
 * This strategy provides a base class for generic animation behaviors for the
 * components in the Large Display Framework. The animation is started when a
 * child of this class receives an event of the "START_ANIMATION" type. The
 * subclass has to provide the implementation of the animate() method, which
 * performs the animation frame update. Optionally, it can also implement the
 * onAnimationStart() and/or onAnimationEnd() methods for having specific
 * actions hapenning in the beginning and/or end of the animation.
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since December 7, 2007
 */
class TOOLKITLAYER_API AnimationStrategy : public VisComponentStrategy
{
	// Attributes
protected:
	/** Flag for starting the animation. */
	bool animating;
	/** The increment for the animation parameter. */
	float animationStep;
	/** The current animation parameter. */
	float animationParameter;
	/** The duration of the animation in seconds. */
	float animationDuration;


	// Methods
public:
	/**
	 * Creates an AnimationStrategy instance.
	 */
	AnimationStrategy(void);
	/**
	 * Destroys this strategy.
	 */
	virtual ~AnimationStrategy(void);

	
	// ACCESSOR METHODS
	/**
	 * Returns the value of the animation step.
	 * @return the value of the animation step.
	 */
	inline float getAnimationStep() { return animationStep; };
	/**
	 * Sets the value of the animation step.
	 * @param value the value of the animation step.
	 */
	inline void setAnimationStep(float value) { animationStep = value; };
	/**
	 * Returns the value of the animation parameter.
	 * @return the value of the animation parameter.
	 */
	inline float getAnimationParameter() { return animationParameter; };
	/**
	 * Sets the value of the animation parameter.
	 * @param value the value of the animation parameter.
	 */
	inline void setAnimationParameter(float value) { animationParameter = value; };
	/**
	 * Returns the current value of the duration of the animation in seconds.
	 *
	 * @return the current value of the duration of the animation in seconds.
	 */
	inline float getAnimationDuration() { return animationDuration; };
	/**
	 * Sets the animation to last the given duration in seconds. In the
	 * beginning of the animation, the value of the animation step is set so
	 * that, when the animation is fully played, it approximately has the
	 * given duration in seconds, based on the application frame rate at the
	 * moment the animation is started. If this value is set as less or equal
	 * than zero, the animation step is not changed.
	 *
	 * @param durationInSecs the approximate duration of the animation in
	 * seconds.
	 */
	inline void setAnimationDuration(float durationInSecs) { animationDuration = durationInSecs; };


protected:
	/**
	 * Performs a given action before rendering the component.
	 */
	void process();
	/**
	 * Handles the given event.
	 *
	 * @param evt the event to be handled.
	 */
	void onEvent(LargeDisplayEvent* evt);

	/**
	 * Carries the frame update that provides the animation of the associated
	 * component. It is run inside the process() method for every animation
	 * frame update.
	 */
	virtual void animate() = 0;
	/**
	 * Performs a specific action when the animation is over.
	 */
	virtual void onAnimationEnd() {};
	/**
	 * Performs a specific action when the animation starts.
	 *
	 * @param evt the event that triggered the animation.
	 */
	virtual void onAnimationStart(LargeDisplayEvent *evt) {};
};

#endif  // ANIMATIONSTRATEGY_H
